"""
控制面板组件
包含文件操作、参数设置等控制功能
"""

from pathlib import Path
from typing import List, Optional
from PySide6.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QLabel, 
    QPushButton, QSlider, QSpinBox, QCheckBox, QProgressBar,
    QTextEdit, QFileDialog
)
from PySide6.QtCore import Qt, Signal

from src.config import config
from src.utils.logger import app_logger
from src.core.license_plate_system import license_plate_system


class ControlPanelWidget(QWidget):
    """
    控制面板组件类
    
    用途：
    - 文件选择和处理控制
    - 参数设置和调整
    - 显示系统信息
    
    信号：
    - image_selected: 选择单张图像时发出
    - batch_selected: 选择多张图像时发出
    - process_requested: 请求开始处理时发出
    - confidence_changed: 置信度阈值改变时发出
    """
    
    image_selected = Signal(str)  # 图像路径
    batch_selected = Signal(list)  # 图像路径列表
    process_requested = Signal()
    confidence_changed = Signal(float)  # 新的置信度值
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.current_files = None
        self.setup_ui()
        self.setup_connections()
        # 初始化时同步置信度阈值
        self._sync_confidence_threshold()
    
    def setup_ui(self):
        """
        设置用户界面
        """
        layout = QVBoxLayout(self)
        
        # 文件操作组
        file_group = self._create_file_group()
        layout.addWidget(file_group)
        
        # 设置组
        settings_group = self._create_settings_group()
        layout.addWidget(settings_group)
        
        # 进度条
        self.progress_bar = QProgressBar()
        progress_height = config.get('gui.controls.progress_bar_height')
        self.progress_bar.setFixedHeight(progress_height)
        self.progress_bar.setVisible(False)
        layout.addWidget(self.progress_bar)
        
        # 系统信息组
        info_group = self._create_info_group()
        layout.addWidget(info_group)
        
        layout.addStretch()
    
    def _create_file_group(self) -> QGroupBox:
        """
        创建文件操作组
        
        返回值：
            QGroupBox: 文件操作组件
        """
        group = QGroupBox("文件操作")
        layout = QVBoxLayout(group)
        
        self.select_image_btn = QPushButton("选择图像")
        self.select_batch_btn = QPushButton("批量选择")
        self.process_btn = QPushButton("开始处理")
        self.process_btn.setEnabled(False)
        
        layout.addWidget(self.select_image_btn)
        layout.addWidget(self.select_batch_btn)
        layout.addWidget(self.process_btn)
        
        return group
    
    def _create_settings_group(self) -> QGroupBox:
        """
        创建设置组
        
        返回值：
            QGroupBox: 设置组件
        """
        group = QGroupBox("设置")
        layout = QVBoxLayout(group)
        
        # 置信度阈值设置
        conf_layout = QHBoxLayout()
        conf_layout.addWidget(QLabel("置信度阈值:"))
        
        # 从配置读取范围和默认值
        conf_range = config.get('gui.controls.confidence_range')
        conf_default = config.get('gui.controls.confidence_default')
        
        self.confidence_slider = QSlider(Qt.Horizontal)
        self.confidence_slider.setRange(*conf_range)
        self.confidence_slider.setValue(conf_default)
        
        self.confidence_spinbox = QSpinBox()
        self.confidence_spinbox.setRange(*conf_range)
        self.confidence_spinbox.setValue(conf_default)
        self.confidence_spinbox.setSuffix("%")
        
        conf_layout.addWidget(self.confidence_slider)
        conf_layout.addWidget(self.confidence_spinbox)
        
        # 保存结果选项
        self.save_results_cb = QCheckBox("保存结果图像")
        self.save_results_cb.setChecked(True)
        
        layout.addLayout(conf_layout)
        layout.addWidget(self.save_results_cb)
        
        return group
    
    def _create_info_group(self) -> QGroupBox:
        """
        创建系统信息组
        
        返回值：
            QGroupBox: 系统信息组件
        """
        group = QGroupBox("系统信息")
        layout = QVBoxLayout(group)
        
        self.info_text = QTextEdit()
        info_height = config.get('gui.controls.info_text_height')
        self.info_text.setMaximumHeight(info_height)
        self.info_text.setReadOnly(True)
        
        # 设置字体
        font_family = config.get('gui.styles.console_font')
        font_size = config.get('gui.styles.console_font_size')
        self.info_text.setStyleSheet(f"font-family: {font_family}; font-size: {font_size}pt;")
        
        self.update_system_info()
        
        layout.addWidget(self.info_text)
        
        return group
    
    def setup_connections(self):
        """
        设置信号连接
        """
        # 按钮连接
        self.select_image_btn.clicked.connect(self.select_image)
        self.select_batch_btn.clicked.connect(self.select_batch)
        self.process_btn.clicked.connect(self.process_requested.emit)
        
        # 滑块和数值框连接
        self.confidence_slider.valueChanged.connect(self.confidence_spinbox.setValue)
        self.confidence_spinbox.valueChanged.connect(self.confidence_slider.setValue)
        self.confidence_slider.valueChanged.connect(self._on_confidence_changed)
    
    def select_image(self):
        """
        选择单张图像
        """
        # 从配置读取支持的文件格式
        file_filter = config.get('file_formats.image_filter')
        
        file_path, _ = QFileDialog.getOpenFileName(
            self, "选择图像文件", "", file_filter
        )
        
        if file_path:
            self.current_files = file_path
            self.process_btn.setEnabled(True)
            self.image_selected.emit(file_path)
            app_logger.info(f"选择图像: {Path(file_path).name}")
    
    def select_batch(self):
        """
        批量选择图像
        """
        # 从配置读取支持的文件格式
        file_filter = config.get('file_formats.image_filter')
        
        file_paths, _ = QFileDialog.getOpenFileNames(
            self, "选择图像文件", "", file_filter
        )
        
        if file_paths:
            # 检查批处理数量限制
            max_batch_size = config.get('performance.max_batch_size')
            if len(file_paths) > max_batch_size:
                app_logger.warning(f"选择的文件数量({len(file_paths)})超过限制({max_batch_size})")
                file_paths = file_paths[:max_batch_size]
            
            self.current_files = file_paths
            self.process_btn.setEnabled(True)
            self.batch_selected.emit(file_paths)
            app_logger.info(f"选择了 {len(file_paths)} 张图像")
    
    def get_current_files(self):
        """
        获取当前选择的文件
        
        返回值：
            str or List[str]: 文件路径或文件路径列表
        """
        return self.current_files
    
    def get_save_results_enabled(self) -> bool:
        """
        获取是否保存结果的设置
        
        返回值：
            bool: 是否保存结果
        """
        return self.save_results_cb.isChecked()
    
    def set_processing_state(self, processing: bool):
        """
        设置处理状态
        
        参数：
            processing (bool): 是否正在处理
        """
        self.process_btn.setEnabled(not processing)
        self.select_image_btn.setEnabled(not processing)
        self.select_batch_btn.setEnabled(not processing)
        
        if processing:
            self.progress_bar.setVisible(True)
            self.progress_bar.setValue(0)
        else:
            self.progress_bar.setVisible(False)
    
    def update_progress(self, value: int):
        """
        更新进度条
        
        参数：
            value (int): 进度值 (0-100)
        """
        self.progress_bar.setValue(value)
    
    def _on_confidence_changed(self, value: int):
        """
        置信度改变处理
        
        参数：
            value (int): 新的置信度值 (0-100)
        """
        threshold = value / 100.0
        self.confidence_changed.emit(threshold)
    
    def update_system_info(self):
        """
        更新系统信息显示
        """
        try:
            info = license_plate_system.get_system_info()
            
            info_text = f"""检测模型: {info.get('detector_model', 'Unknown')}
识别语言: {', '.join(info.get('recognizer_languages', []))}
置信度阈值: {info.get('confidence_threshold', 0):.2f}
IoU阈值: {info.get('iou_threshold', 0):.2f}
输出目录: {info.get('output_directory', 'Unknown')}"""
            
            self.info_text.setPlainText(info_text)
            
        except Exception as e:
            app_logger.error(f"更新系统信息失败: {e}")
            self.info_text.setPlainText("系统信息获取失败")
    
    def _sync_confidence_threshold(self):
        """
        同步置信度阈值：将系统的置信度阈值同步到GUI滑块
        """
        try:
            # 获取系统当前的置信度阈值
            info = license_plate_system.get_system_info()
            current_threshold = info.get('confidence_threshold', 0.25)
            
            # 转换为百分比并设置到滑块
            slider_value = int(current_threshold * 100)
            
            # 临时断开信号连接，避免触发更新
            self.confidence_slider.blockSignals(True)
            self.confidence_spinbox.blockSignals(True)
            
            # 设置滑块和数值框的值
            self.confidence_slider.setValue(slider_value)
            self.confidence_spinbox.setValue(slider_value)
            
            # 重新连接信号
            self.confidence_slider.blockSignals(False)
            self.confidence_spinbox.blockSignals(False)
            
            app_logger.info(f"GUI置信度阈值已同步为: {current_threshold:.2f} ({slider_value}%)")
            
        except Exception as e:
            app_logger.error(f"同步置信度阈值失败: {e}")
    
    def get_confidence_threshold(self) -> float:
        """
        获取当前置信度阈值
        
        返回值：
            float: 置信度阈值 (0.0-1.0)
        """
        return self.confidence_slider.value() / 100.0 